#include"I2C.h"
#include"Delay.h"

//初始化
void iic_init(void)
{
     RCC->APB2ENR|=RCC_APB2ENR_IOPBEN;

    GPIOB->CRH|=GPIO_CRH_MODE10;
    GPIOB->CRH|=GPIO_CRH_CNF10_0;
    GPIOB->CRH&=~GPIO_CRH_CNF10_1;
    GPIOB->CRH|=GPIO_CRH_MODE11;
    GPIOB->CRH|=GPIO_CRH_CNF11_0;
    GPIOB->CRH&=~GPIO_CRH_CNF11_1;
}
//开始信号
void iic_start(void)
{
    //首先在SCL和SDA都为高电平
    SCL_HIGH;
    SDA_HIGH;
    IIC_DELAY;
    //在SCL处于高电平状态，SDA拉低，表示开始
    SDA_LOW;
    IIC_DELAY;
    
}
//停止信号
void iic_stop(void)
{
    //首先在SCL为高电平 SDA为低电平
    SCL_HIGH;
    SDA_LOW;
    IIC_DELAY;
    //在SCL处于高电平状态，SDA拉高，表示结束
    SDA_HIGH;
    IIC_DELAY;
}

//主机应答
//对于应答信号，在SCL为低的时候 SDA拉低
void iic_Ack(void)
{
    //1.SCL为低，SDA为高
    SCL_LOW;
    SDA_HIGH;
    IIC_DELAY;
    //2.SCL为低，SDA拉低
    SDA_LOW;
    IIC_DELAY;
    //3.SDA保持，SCL拉高,保持，采样
    SCL_HIGH;
    IIC_DELAY;
    //4.SCL拉低
    SCL_LOW;
    IIC_DELAY;
    //5.SCL保持 SDA还原拉高
    SDA_HIGH;
    IIC_DELAY;
}
//主机不应答
void iic_Nack(void)
{
    SCL_LOW;
    SDA_HIGH;
    IIC_DELAY;

    SCL_HIGH;
    IIC_DELAY;

    SCL_LOW;
    IIC_DELAY;
}

uint8_t wait_ack(void)
{
    //1.SCL拉低，SDA拉高
    SCL_LOW;
    SDA_HIGH;
    IIC_DELAY;

    //2.SCL拉高，
    SCL_HIGH;
    IIC_DELAY;
    //3.采样
    uint16_t ack=SDA_WRITE;
    //4.SCL拉低
    SCL_LOW;
    IIC_DELAY;

    return ack? 1:0;
}
//写信号
void iic_write(uint8_t byte)
{
    //1.SDA拉低SCL拉低
    SCL_LOW;
    SDA_LOW;
    IIC_DELAY;
    //2.SDA开始写数据，SCL不变
    /*在IIC（总线中，数据是按字节（8位）进行传输的。在单字节写入作中，通常是从高位先写。
    具体来说，IIC协议规定数据字节的传输是从最高位（MSB，Most Significant Bit）开始，
    然后逐步传输到最低位（LSB，Least Significant Bit）。*/
    for(uint8_t i=0;i<8;i++)
    {
        if(byte & 0x80)
        {
            SDA_HIGH;
        }
        else
        {
            SDA_LOW;
        }
        IIC_DELAY;

        //3.SCL拉高，采集
        SCL_HIGH;
        IIC_DELAY;

        //4.采样完成 SCL拉低
        SCL_LOW;
        IIC_DELAY;

        //5.拉低又要开始传输数据，回到循环，此时要传输第二个
        byte<<=1;
    }
    
}

uint8_t iic_read(void)
{
    uint8_t data=0;
    //1.先把SCL拉低，SDA不能碰，因为是接收信号
    SCL_LOW;
    IIC_DELAY;

    for(uint8_t i=0;i<8;i++)
    {
        //2.把SCL拉高，要开始采集信号
        SCL_HIGH;
        IIC_DELAY;

        //3.开始采集信号
        data<<=1;
        if (SDA_WRITE)
        {
            data|=0x01;
        }
        IIC_DELAY;
        //4.采集完成 SCL拉低
        SCL_LOW;
        IIC_DELAY; 
    }
    return data;
}